#include "tda_gestor_incidencias.h"

int TGI_AgregarUsuario(TGI* tgi, int user_id, const char* user_name)
{
    user_t useraux;

    if(!ls_Vacia(tgi->usuarios)) /*si la lista de usuarios no esta vacia verifico que el id no sea repetido*/{
        ls_MoverCorriente(&tgi->usuarios, LS_PRIMERO);
        do{
            ls_ElemCorriente(tgi->usuarios, &useraux);
            if (useraux.user_id==user_id){
                fprintf(stderr,"%s","ERROR ID_USER YA INGRESADO");
                return ERR_ID_USER_EXISTENTE;
            }
        }
        while (ls_MoverCorriente(&tgi->usuarios, LS_SIGUIENTE));
    }

    /* Creo el usuario a ser agregado*/
    useraux.user_id = user_id;
    useraux.user_name = (char*)malloc(sizeof(char)*strlen(user_name)+1);
    strcpy(useraux.user_name, user_name);

    /* Lo inserto en la lista */
    if(ls_Insertar(&tgi->usuarios, LS_SIGUIENTE, &useraux))
    {
        /*Actualizo el contador de max_id_usuario */
        if(useraux.user_id > tgi->max_id_usuario)
            tgi->max_id_usuario = useraux.user_id;
    }
    else
        return ERR_UNDEFINED;

    return RES_OK;
}

int TGI_GetUsuario(const TGI* tgi, int usuario, user_t* info_usuario)
{
    int N;
    user_t useraux;
    TListaSimple auxUsuarios;

    memcpy(&auxUsuarios, &tgi->usuarios, sizeof(auxUsuarios)); /*hago memcpy de la lista de usuarios*/

    ls_MoverCorriente(&auxUsuarios,LS_PRIMERO);
    do{
        ls_ElemCorriente(auxUsuarios,&useraux);
        if (useraux.user_id==usuario){ /*verifico que el id de usuario exista*/
            info_usuario->user_id=useraux.user_id; /*si existe copio la info*/
            N=strlen(useraux.user_name);
            info_usuario->user_name=(char*)malloc(sizeof(char)*N+1);
            strcpy(info_usuario->user_name,useraux.user_name);
            return RES_OK;
        }
    }
    while (ls_MoverCorriente(&auxUsuarios,LS_SIGUIENTE));

    return ERR_ID_USER_INEXISTENTE;
}

int TGI_GetProyecto(const TGI* tgi, int proyecto, project_t* info_proyecto)
{
    int N;
    project_t proaux;
    TListaSimple auxProyectos;

    memcpy(&auxProyectos, &tgi->proyectos, sizeof(auxProyectos)); /*hago memcpy de la lista de proyectos*/

    ls_MoverCorriente(&auxProyectos,LS_PRIMERO);
    do
    {
        ls_ElemCorriente(auxProyectos,&proaux);
        if (proaux.project_id==proyecto) /*verifico que el id de proyecto exista*/
        {
            info_proyecto->project_id=proaux.project_id; /*si existe copio la info*/
            N=strlen(proaux.project_name);
            info_proyecto->project_name=(char*)malloc(sizeof(char)*N+1);
            strcpy(info_proyecto->project_name,proaux.project_name);
            return RES_OK;
        }
    }
    while (ls_MoverCorriente(&auxProyectos,LS_SIGUIENTE));

    return ERR_ID_PROJECT_INEXISTENTE;
}

int TGI_AgregarProyecto(TGI* tgi, int project_id, const char* project_name)
{
    project_t proaux;
    int N;

    /** DEBUG: Se podria cambiar para usar GetProyecto no? */
    if(!ls_Vacia(tgi->proyectos)) /*si la lista de proyectos no esta vacia verifico que el id no sea repetido*/
    {
        ls_MoverCorriente(&tgi->proyectos, LS_PRIMERO);
        do
        {
            ls_ElemCorriente(tgi->proyectos, &proaux);
            if (proaux.project_id==project_id)
            {
                fprintf(stderr,"%s","ERROR ID_PROJECT YA INGRESADO");
                return ERR_ID_PROJECT_EXISTENTE;
            }
        }
        while (ls_MoverCorriente(&tgi->proyectos, LS_SIGUIENTE));
    }

    /* Creo el proyecto a ser agregado*/
    proaux.project_id = project_id;
    N=strlen(project_name);
    proaux.project_name = (char*)malloc(sizeof(char)*(N+1));
    strcpy(proaux.project_name, project_name);
    /* Lo inserto en la lista */
    if(ls_Insertar(&tgi->proyectos, LS_SIGUIENTE, &proaux))
        {
            if(proaux.project_id > tgi->max_id_proyecto)
                tgi->max_id_proyecto = proaux.project_id;
                else return ERR_UNDEFINED;
        }


    return RES_OK;
}

int CargarProyectos( TGI* tgi, const char* proyectos)
{
    FILE* archProyectos;
    char* campo;
    char* linea;
    int project_id;
    char* project_name;
    char* delim = ";";

    /*Crea la una lista de proyectos*/
    ls_Crear(&tgi->proyectos,sizeof(project_t));
    /* Inicializo el contador de maximo id proyecto */
    tgi->max_id_proyecto = 0;
    /*Me fijo si existe el archivo, si existe cargo en la lista
    todo los datos que contengan.*/
    archProyectos = fopen(proyectos,"r");
    if(archProyectos)
    {
        /*Mientras no sea fin de archivo*/
        while(!feof(archProyectos))
        {
            /*voy obteninedo los valores*/
            if(getString(&linea, archProyectos) == RES_OK)
            {
                linea[(strlen(linea)*sizeof(char))-1]='\0'; /*Parche saca barra n */

            	/*Separo la linea dado que viene del formato 1;proyectouno */
                campo = strtok(linea, delim);
                /* Chequeo si es numero y lo convierto */
                if(!strIsInt(campo))
                {
                    /** DEBUG: Habria que saltear la linea y escupir un error, pero seguir procesando el archivo */
                }
                else
                {
                    /* Agrego el proyecto */
                    project_id = atoi(campo);
                    project_name = strtok(NULL, delim);

                    /*Inserto el proyecto en la lista*/
                    if(TGI_AgregarProyecto(tgi, project_id, project_name) != RES_OK)
                    {
                        /** DEBUG: No se pudo agregar el proyecto */
                    }
                }
                free(linea);
            }
        }
        fclose(archProyectos);
    }

    return RES_OK;
}

int CargarUsuarios( TGI* tgi, const char* usuarios)
{
    FILE* archUsuarios;
    char* campo;
    char* linea;
    int user_id;
    char* user_name;
    char* delim = ";";

    /*Crea la lista de usuarios*/
    ls_Crear(&tgi->usuarios,sizeof(user_t));
    /* Inicializo el contador de maximo id proyecto */
    tgi->max_id_usuario = 0;
    /*Me fijo si existe el archivo, si existe cargo en la lista
    todo los datos que contengan.*/
    archUsuarios = fopen(usuarios,"r");
    if(archUsuarios)
    {
        /*Mientras no sea fin de archivo*/
        while(!feof(archUsuarios))
        {
            /*voy obteninedo los valores*/
            if(getString(&linea, archUsuarios) == RES_OK)
            {
                linea[(strlen(linea)*sizeof(char))-1]='\0'; /*Parche saca barra n */

            	/*Separo la linea dado que viene del formato 1;proyectouno */
                campo = strtok(linea, delim);
                /* Chequeo si es numero y lo convierto */
                if(!strIsInt(campo))
                {
                    /** DEBUG: Habria que saltear la linea y escupir un error, pero seguir procesando el archivo */
                }
                else
                {
                    /* Agrego el usuario */
                    user_id = atoi(campo);
                    user_name = strtok(NULL, delim);

                    /*Inserto el usuario en la lista*/
                    if(TGI_AgregarUsuario(tgi, user_id, user_name) != RES_OK)
                    {
                        /** DEBUG: No se pudo agregar el usuario */
                    }
                }
                free(linea);
            }
        }
        fclose(archUsuarios);
    }
    return RES_OK;
}




int ActualizarEstados(TListaSimple* incidencias,int inci_id,int usuario_id,char* fecha,stat_inci_t estado)
{
    TIN tinaux;
    /*inci_status_t stataux;
    int N;*/


    if(!ls_Vacia(*incidencias)) /*si la lista de incidencias no est� vacia  busco el id*/
    {
        ls_MoverCorriente(incidencias, LS_PRIMERO);
        do
        {
            ls_ElemCorriente(*incidencias,&tinaux); /*obtengo el elemento corriente*/
            if (tinaux.inci_id==inci_id) /*si son iguales*/
            {
                    /*N=strlen(fecha);
                    stataux.stat_date=malloc(sizeof(char)*(N+1));
                    strcpy(stataux.stat_date,fecha); copio la fecha
                    stataux.stat_user_id=usuario_id; copio el usuario
                    stataux.stat_desc=estado; copio el estado
                    ls_Insertar(&tinaux.inci_stat_hist,LS_SIGUIENTE,&stataux); si la lista de estados est� vacia inserto en el primero*/
                    TIN_CambiarEstado(&tinaux,fecha,usuario_id,estado);

                    ls_ModifCorriente(incidencias,&tinaux); /*modifico la incidencia corriente*/

                    return ERR_ID_INCIDENCIA_EXISTENTE;
            }
        }
        while (ls_MoverCorriente(incidencias, LS_SIGUIENTE));
    } else return ERR_LISTA_VACIA;

    return ERR_ID_INCIDENCIA_INEXISTENTE;

}

int ActualizarComentarios(TListaSimple* incidencias,int inci_id,int usuario_id,char* fecha,char* comentario,int cod,resol_inci_t resolucion)
{
    TIN tinaux;
    /*inci_comment_t commaux;
    int N;*/

/**Esta funcion hace 2 cosas despende de la situacion: se encarga de grabar un nuevo comentario de una incidencia
en su lista de comentarios, y cuando se registra la resolucion de una incidencia la registra y hace un comentario
porque en el programa de aplicacion el unico momento que se hace un comentario es cuando se resuelve la incidencia.
*/

    if(!ls_Vacia(*incidencias)) /*si la lista de comentarios no est� vacia busco el id*/
    {
        ls_MoverCorriente(incidencias, LS_PRIMERO);
        do
        {
            ls_ElemCorriente(*incidencias,&tinaux); /*obtengo el corriente*/
            if (tinaux.inci_id==inci_id)
            {
                    /*N=strlen(fecha);
                    commaux.comm_date=malloc(sizeof(char)*(N+1));
                    strcpy(commaux.comm_date,fecha);
                    commaux.comm_user_id=usuario_id;
                    N=strlen(comentario);
                    commaux.comm_desc=malloc(sizeof(char)*(N+1));
                    strcpy(commaux.comm_desc,comentario);
                    ls_Insertar(&tinaux.inci_comm,LS_SIGUIENTE,&commaux);*/
                    if (cod==COM_CAMBIAR_ESTADO_INCIDENCIA) /**si hay que cambiar el estado lo cambia, sino solo comenta*/
                       TIN_Resolver(&tinaux,fecha,usuario_id,resolucion);
                    TIN_Comentar(&tinaux,fecha,usuario_id,comentario);

                    ls_ModifCorriente(incidencias,&tinaux);

                    return ERR_ID_INCIDENCIA_EXISTENTE;
            }
        }
        while (ls_MoverCorriente(incidencias, LS_SIGUIENTE));
    } else return ERR_LISTA_VACIA;

    return ERR_ID_INCIDENCIA_INEXISTENTE;

}

int CargarIncidencias( TGI* tgi, const char* incidencias)
{
    FILE* archIncidencias;
    TIN tin;
    char* campo;
    char* linea;
    char* estados;
    char* comentarios;

    int inci_id;
    tipo_inci_t inci_type;
    prior_inci_t inci_priority;
    int inci_user;
    int inci_assigned_user;
    char* inci_date_created;
    int inci_project_id;
    char* inci_summary;
    char* inci_description;
    resol_inci_t inci_resolved;
    char* inci_date_solved;
    int error;
    char* fecha;
    int usuario_id;
    char* comentario;
    stat_inci_t estado;
    int cod;

    char* delim = ";";


    /* Armo la ruta a los archivos de comentarios y estados en base al de incidencias */
    estados = (char*)malloc(sizeof(char) * (strlen(incidencias) + 6));
    comentarios = (char*)malloc(sizeof(char) * (strlen(incidencias) + 6));
    strcpy(estados, incidencias);
    strcpy(comentarios, incidencias);
    strcat(estados, ".esta");
    strcat(comentarios, ".come");

    /*Crea la lista de indicencias */
    ls_Crear(&tgi->incidencias, sizeof(TIN));
    /* Inicializo el contador de maximo id incidencia */
    tgi->max_id_incidencia = 0;
    /*Me fijo si existe el archivo, si existe cargo en la lista
    todo los datos que contengan.*/
    archIncidencias = fopen(incidencias, "r");
    if(archIncidencias)
    {
        /*Mientras no sea fin de archivo*/
        while(!feof(archIncidencias))
        {
            /*voy obteninedo los valores*/
            if(getString(&linea,archIncidencias) == RES_OK)
            {
                linea[(strlen(linea)*sizeof(char))-1]='\0'; /*Parche saca barra n */

            	if( (campo = strtok(linea, delim)) != NULL )
                    inci_id = atoi(campo);

                if( (campo = strtok(NULL, delim)) != NULL ){
                    inci_type = atoi(campo);
                }
                if( (campo = strtok(NULL, delim)) != NULL ){
                    inci_priority = atoi(campo);
                }
                if( (campo = strtok(NULL, delim)) != NULL ){
                    inci_user = atoi(campo);
                }
                if( (campo = strtok(NULL, delim)) != NULL ){
                    inci_assigned_user = atoi(campo);
                }
                if( (campo = strtok(NULL, delim)) != NULL ){
                    inci_date_created = campo;
                }
                if( (campo = strtok(NULL, delim)) != NULL ){
                    inci_project_id = atoi(campo);
                }
                if( (campo = strtok(NULL, delim)) != NULL ){
                    inci_summary = campo;
                }
                if( (campo = strtok(NULL, delim)) != NULL ){
                    inci_description = campo;
                }
                if( (campo = strtok(NULL, delim)) != NULL ){
                    inci_resolved = atoi(campo);
                }
                if( (campo = strtok(NULL, delim)) != NULL ){
                    inci_date_solved = campo;
                }

                /* Agrego la incidencia */
                TIN_Crear (&tin,inci_id,inci_type,inci_priority,inci_user,inci_assigned_user,inci_date_created,inci_project_id,inci_summary,inci_description );
                ls_Insertar(&tgi->incidencias, LS_SIGUIENTE, &tin);
                /*Actualizo el contador de max_id_incidencia */
                if(inci_id > tgi->max_id_incidencia)
                    tgi->max_id_incidencia = inci_id;

                free(linea);
            }
        }
        fclose(archIncidencias);
    }

    /* Cargo los estados de las incidencias */
    archIncidencias = fopen(estados, "r");
    if(archIncidencias)
    {
        /*Mientras no sea fin de archivo*/
        while(!feof(archIncidencias))
        {
            if(getString(&linea, archIncidencias) == RES_OK)
            {
                linea[(strlen(linea)*sizeof(char))-1]='\0'; /*Parche saca barra n */

                campo = strtok(linea, delim);
                /* Chequeo si es numero y lo convierto */
                if(!strIsInt(campo)){
                    /** DEBUG: Habria que saltear la linea y escupir un error, pero seguir procesando el archivo */
                }
                else{
                    error=0;
                    inci_id = atoi(campo);
                    if( (campo = strtok(NULL, delim)) != NULL ){
                        fecha = campo;
                    }else{error = 1;}
                    if( (campo = strtok(NULL, delim)) != NULL ){
                        usuario_id = atoi(campo);
                    }else{error = 1;}
                    if( (campo = strtok(NULL, delim)) != NULL ){
                        estado = atoi(campo);
                    }else{error = 1;}

                    if(!error)
                    {
                        if (ActualizarEstados(&tgi->incidencias,inci_id,usuario_id,fecha,estado)==ERR_ID_INCIDENCIA_INEXISTENTE)
                                {
                                    /*ERROR*/
                                }
                        /*if(TGI_GetIncidencia(tgi, inci_id, &tin) == RES_OK)
                        {
                            TIN_CambiarEstado(&tin, fecha, usuario_id, estado);
                             DEBUG: Lo que pasa es que aca se actualiza la tin, pero esa tin es de una lista copiada (en TGI_GetIncidencia), por
                                ende no se actualiza en la lista original, si no en la copia... Habria que hacer un TGI_ActualizarIncidencia o algo asi
                                que recorra la lista original, busque la incidencia y haga ls_ModifCorriente
                        }*/
                    }
                }
                free(linea);
            }
        }
        fclose(archIncidencias);
    }

    /* Cargo los comentarios de las incidencias */
    archIncidencias = fopen(comentarios, "r");
    if(archIncidencias)
    {
        /*Mientras no sea fin de archivo*/
        while(!feof(archIncidencias))
        {
            if(getString(&linea, archIncidencias) == RES_OK)
            {
                linea[(strlen(linea)*sizeof(char))-1]='\0'; /*Parche saca barra n */

                campo = strtok(linea, delim);
                /* Chequeo si es numero y lo convierto */
                if(!strIsInt(campo)){
                    /** DEBUG: Habria que saltear la linea y escupir un error, pero seguir procesando el archivo */
                }
                else{
                    inci_id = atoi(campo);

                    if( (campo = strtok(NULL, delim)) != NULL ){
                        fecha = campo;
                    }else{error = 1;}
                    if( (campo = strtok(NULL, delim)) != NULL ){
                        usuario_id = atoi(campo);
                    }else{error = 1;}
                    if( (campo = strtok(NULL, delim)) != NULL ){
                        comentario = campo;
                    }else{error = 1;}

                    if(!error)
                    {
                        cod=-1;
                        if (ActualizarComentarios(&tgi->incidencias,inci_id,usuario_id,fecha,comentario,cod,-1)==ERR_ID_INCIDENCIA_INEXISTENTE)
                        {
                            /*ERROR*/

                        }


                        /*if(TGI_GetIncidencia(tgi, inci_id, &tin) == RES_OK)
                            TIN_Comentar(&tin, fecha, usuario_id, comentario);*/
                    }
                }
                free(linea);
            }
        }
        fclose(archIncidencias);
    }
    free(estados);
    free(comentarios);
    return RES_OK;
}

int TGI_Crear ( TGI* tgi, const char* proyectos, const char* usuarios, const char* incidencias )
{
    CargarProyectos(tgi, proyectos);
    CargarUsuarios(tgi, usuarios);
    CargarIncidencias(tgi, incidencias);

    return RES_OK;
}

int TGI_AgregarIncidencia ( TGI* tgi, tipo_inci_t inci_type, prior_inci_t inci_priority, int inci_user, int inci_assigned_user,
                            char* inci_date_created, int inci_project_id, char* inci_summary, char* inci_description )
{
    int res;
    project_t project;
    user_t usuario;
    TIN incidencia;


    /* Chequeo si existe el proyecto */
    if(TGI_GetProyecto(tgi, inci_project_id, &project) != RES_OK)
        return ERR_PROYECTO_INEXISTENTE;
    free(project.project_name);

    /* Chequeo si existe el usuario */
    if(TGI_GetUsuario(tgi, inci_user, &usuario) != RES_OK)
        return ERR_USUARIO_INEXISTENTE;
    free(usuario.user_name);

    /* Creo la incidencia */
    tgi->max_id_incidencia++;/* Actualizo el maximo id de incidencia existente */
    res = TIN_Crear(&incidencia, tgi->max_id_incidencia, inci_type, inci_priority, inci_user, inci_assigned_user,
                    inci_date_created, inci_project_id, inci_summary, inci_description);
    if(res != RES_OK)
        return res;

    /* Agrego la incidencia creada a la lista */

     do
    {
       /* dice quimey: "ESTO ESTA MAL!!!!" :D arecorro la lista de incidencias, para llegar al ultimo y grabar la nueva incidencia en ese lugar*/
    }
    while (ls_MoverCorriente(&tgi->incidencias,LS_SIGUIENTE));

    if(!ls_Insertar(&tgi->incidencias, LS_SIGUIENTE, &incidencia))
    {
        TIN_Liberar(&incidencia);
        return ERR_UNDEFINED;
    }


    return RES_OK;
}

int TGI_GetIncidencia( const TGI* tgi, int inci, TIN* tin )
{
	TIN auxTin;
	TListaSimple auxIncidencias;

	/* Copio la lista de incidencias para recorrerla y no modificar la original */
    memcpy(&auxIncidencias, &tgi->incidencias, sizeof(auxIncidencias));

	if(ls_Vacia(auxIncidencias))
	{
		/*No hay incidencias */
		return ERR_LISTA_VACIA;
	}

    ls_MoverCorriente(&auxIncidencias, LS_PRIMERO);
    do
    {
        ls_ElemCorriente(auxIncidencias, &auxTin);
        if (auxTin.inci_id == inci) /*comparo el id de la incidenica*/
        {
            /** DEBUG: Hay que copiar la incidencia, porque la consigna dice que la memoria alocada debe ser liberada por el invocador */
            /* Se encontro la incidencia */
            memcpy(tin, &auxTin, sizeof(TIN));
            /*TIN_RealocarStrings(tin);*/
            return RES_OK;
        }
    }
    while (ls_MoverCorriente(&auxIncidencias, LS_SIGUIENTE));

    return -1; /* No se encontro la incidencia */
}

int TGI_GetIncidenciasUsuario(const TGI* tgi, int usuario, TCola* incidencias)
{
    TListaSimple auxIncidencias;
    bool existeIncidencia;
    TIN incidencia;
    existeIncidencia = false;

    /* Copio la lista de incidencias para recorrerla y no modificar la original */
    memcpy(&auxIncidencias, &tgi->incidencias, sizeof(auxIncidencias));

    /* Muevo el corriente de la lista de incidencias al principio */
    if(!ls_MoverCorriente(&auxIncidencias, LS_PRIMERO))
        return ERR_OTRO;

    /* Recorro la lista de incidencias */
    do
    {
        /* Obtengo la incidencia corriente */
        ls_ElemCorriente(auxIncidencias, &incidencia);

        /* Pregunto si el usuario de la incidencia coincide con el pedido */
        if(incidencia.inci_user == usuario)
        {
            /* Copio los elementos de la incidencia */
            if(!TIN_RealocarStrings(&incidencia))
                return ERR_OTRO;

            /* Agrego la incidencia a la cola */
            if(!C_Agregar(incidencias, &incidencia))
                return ERR_OTRO;

            existeIncidencia = true;
        }
    }
    /* Mientras exista un elemento siguiente al corriente */
    while(ls_MoverCorriente(&auxIncidencias, LS_SIGUIENTE));

    return existeIncidencia ? RES_OK : ERR_NO_HAY_INCIDENCIAS;
}

int TGI_GetIncidenciasProyecto(const TGI* tgi, int proyecto, TListaSimple* incidencias )
{
    TListaSimple auxIncidencias;
    bool existeIncidencia;
    TIN incidencia;
    existeIncidencia = false;

    /* Copio la lista de incidencias para recorrerla y no modificar la original */
    memcpy(&auxIncidencias, &tgi->incidencias, sizeof(auxIncidencias));

    /* Muevo el corriente de la lista de incidencias al principio */
    if(!ls_MoverCorriente(&auxIncidencias, LS_PRIMERO))
        return ERR_OTRO;

    /* Recorro la lista de incidencias */
    do
    {
        /* Obtengo la incidencia corriente */
        ls_ElemCorriente(auxIncidencias, &incidencia);

        /* Pregunto si el proyecto de la incidencia coincide con el pedido */
        if(incidencia.inci_project_id == proyecto)
        {
            /* Copio los elementos de la incidencia */
            if(!TIN_RealocarStrings(&incidencia))
                return ERR_OTRO;

            /* Agrego la incidencia a la cola */
            if(!ls_Insertar(incidencias, LS_SIGUIENTE, &incidencia))
                return ERR_OTRO;

            existeIncidencia = true;
        }
    }
    /* Mientras exista un elemento siguiente al corriente */
    while(ls_MoverCorriente(&auxIncidencias, LS_SIGUIENTE));

    return existeIncidencia ? RES_OK : ERR_NO_HAY_INCIDENCIAS;
}

int GrabarEstados(FILE* archStat, TListaSimple* estados, int id)
{
    inci_status_t stataux;

    if(ls_MoverCorriente(estados,LS_PRIMERO))
    	do{ /*recorro el historial de Comentarios, grabando los datos*/
			ls_ElemCorriente(*estados,&stataux);
			fprintf(archStat,"%d",id);
			fprintf(archStat,"%c",';');
			fprintf(archStat,"%s",stataux.stat_date);
			fprintf(archStat,"%c",';');
			fprintf(archStat,"%d",stataux.stat_user_id);
			fprintf(archStat,"%c",';');
			fprintf(archStat,"%d\n",stataux.stat_desc);

    	}while (ls_MoverCorriente(estados,LS_SIGUIENTE));

    return RES_OK;
}

int GrabarComentarios(FILE* archComm, TListaSimple* comentarios, int id)
{
    inci_comment_t commaux;

    if(ls_MoverCorriente(comentarios,LS_PRIMERO))
		do{ /*recorro el historial de Comentarios, grabando los datos*/
			ls_ElemCorriente(*comentarios,&commaux);
			fprintf(archComm,"%d",id);
			fprintf(archComm,"%c",';');
			fprintf(archComm,"%s",commaux.comm_date);
			fprintf(archComm,"%c",';');
			fprintf(archComm,"%d",commaux.comm_user_id);
			fprintf(archComm,"%c",';');
			fprintf(archComm,"%s\n",commaux.comm_desc);
		}while (ls_MoverCorriente(comentarios,LS_SIGUIENTE));


    return RES_OK;
}

int GrabarIncidencias(FILE* archIncidencias, TListaSimple* incidencia, const char* R_Incidencia)
{
    TIN inciaux;
    FILE *archComm;
    FILE *archStat;
    char* rutaComm;
    char* rutaStat;
    int N;

    N=strlen(R_Incidencia);
    rutaComm=(char*)malloc(sizeof(char)*(N+5+1));
    strcpy(rutaComm,R_Incidencia);
    strcat(rutaComm,".come"); /*agrego el .COME a la ruta de incidencia*/
    archComm = fopen(rutaComm,"w");/*ABRO EL ARCHIVO DE COMENTARIOS , NECESITO ABRIRLO AC� PARA ESCRITURA*/
    if (!archComm){

        return -1;
    }

    N=strlen(R_Incidencia);
    rutaStat=(char*)malloc(sizeof(char)*(N+5+1));
    strcpy(rutaStat,R_Incidencia);
    strcat(rutaStat,".esta");/*agrego el .ESTA a la ruta de incidencia*/
    archStat = fopen(rutaStat,"w");/*ABRO EL ARCHIVO DE ESTADOS, NECESITO ABRIRLO AC� PARA ESCRITURA*/
    if (!archStat){

        return -1;
    }
    ls_MoverCorriente(incidencia,LS_PRIMERO);

		do{     /*recorro la lista de incidencias, grabando los datos menos los comentarios y los estados*/
			ls_ElemCorriente(*incidencia,&inciaux);

			fprintf(archIncidencias,"%d",inciaux.inci_id);
			fprintf(archIncidencias,"%c",';');

			fprintf(archIncidencias,"%d",inciaux.inci_type);
			fprintf(archIncidencias,"%c",';');

			fprintf(archIncidencias,"%d",inciaux.inci_priority);
			fprintf(archIncidencias,"%c",';');

			fprintf(archIncidencias,"%d",inciaux.inci_user);
			fprintf(archIncidencias,"%c",';');

			fprintf(archIncidencias,"%d",inciaux.inci_assigned_user);
			fprintf(archIncidencias,"%c",';');

			fprintf(archIncidencias,"%s",inciaux.inci_date_created);
			fprintf(archIncidencias,"%c",';');

			fprintf(archIncidencias,"%d",inciaux.inci_project_id);
			fprintf(archIncidencias,"%c",';');

			fprintf(archIncidencias,"%s",inciaux.inci_summary);
			fprintf(archIncidencias,"%c",';');

			fprintf(archIncidencias,"%s",inciaux.inci_description);
			fprintf(archIncidencias,"%c",';');

			fprintf(archIncidencias,"%d",inciaux.inci_resolved);
			fprintf(archIncidencias,"%c",';');

			fprintf(archIncidencias,"%s\n",inciaux.inci_date_solved); /*al �ltimo le pogo salto de l�nea*/


			GrabarComentarios(archComm,&inciaux.inci_comm,inciaux.inci_id); /*grabo los comentarios*/
			GrabarEstados(archStat,&inciaux.inci_stat_hist,inciaux.inci_id);/*grabo las incidencias*/



		}while (ls_MoverCorriente(incidencia,LS_SIGUIENTE));

    fclose(archComm);
    free(rutaComm);
    fclose(archStat);
    free(rutaStat);

    return RES_OK;
}

int GrabarProyectos(FILE* archProyectos, TListaSimple* project)
{
    project_t proaux;

    ls_MoverCorriente(project,LS_PRIMERO);
    do{ /*recorro la lista de proyectos, grabando los datos*/
        ls_ElemCorriente(*project,&proaux);
        fprintf(archProyectos,"%d",proaux.project_id);
        fprintf(archProyectos,"%c",';');
        fprintf(archProyectos,"%s\n",proaux.project_name);

    }while (ls_MoverCorriente(project,LS_SIGUIENTE));

    return RES_OK;
}

int GrabarUsuarios(FILE* archUsuarios, TListaSimple* users)
{
    user_t usuaux;

    ls_MoverCorriente(users,LS_PRIMERO);
    do{ /*recorro la lista de proyectos, grabando los datos*/
        ls_ElemCorriente(*users,&usuaux);
        fprintf(archUsuarios,"%d",usuaux.user_id);
        fprintf(archUsuarios,"%c",';');
        fprintf(archUsuarios,"%s\n",usuaux.user_name);

    }while (ls_MoverCorriente(users,LS_SIGUIENTE));

    return RES_OK;
}

int TGI_Grabar(TGI* tgi, const char* R_Usuario, const char* R_Proyecto, const char* R_Incidencia)
{
    FILE *archProyectos;
    FILE *archUsuarios;
    FILE *archIncidencias;

    archProyectos = fopen(R_Proyecto,"w"); /*los abro aca xq en CREAR no los cierra pero la variable local que manipula los archivos se destruye �Quedan abiertos o no?*/
    if (!archProyectos) {
        fprintf(stderr,"%s","ERROR AL ABRIR PROYECTOS");
        return -1;
    }
    GrabarProyectos(archProyectos,&tgi->proyectos); /*graba proyectos*/
    fclose(archProyectos);

    archUsuarios = fopen(R_Usuario,"w");/*IDEM CON PROYECTOS*/
    if (!archUsuarios){
        fprintf(stderr,"%s","ERROR AL ABRIR USUARIOS");
        return -1;
    }
    GrabarUsuarios(archUsuarios,&tgi->usuarios);
    fclose(archUsuarios);

    archIncidencias = fopen(R_Incidencia,"w");/*IDEM CON PROYECTOS*/
    if (!archIncidencias){
        fprintf(stderr,"%s","ERROR AL ABRIR INCIDENCIAS");
        return -1;
    }

    GrabarIncidencias(archIncidencias,&tgi->incidencias,R_Incidencia);

    fclose(archIncidencias);

    return RES_OK;

}

int Cerrar_User(TListaSimple* usuario)
{
    user_t usuaux;

    if(ls_MoverCorriente(usuario,LS_PRIMERO))
    {
        do{ /*recorro la lista de usuario, liberando el char* user_name*/
            ls_ElemCorriente(*usuario,&usuaux);
            free(usuaux.user_name);
        }while (ls_MoverCorriente(usuario,LS_SIGUIENTE));

        ls_Vaciar(usuario); /*borro la lista de usuarios*/
    }

    return RES_OK;

}

int Cerrar_Project(TListaSimple* project)
{
    project_t proaux;

    if(ls_MoverCorriente(project,LS_PRIMERO))
    {
        do{ /*recorro la lista de proyectos, liberando el char* project_name*/
            ls_ElemCorriente(*project,&proaux);
            free(proaux.project_name);
        }while (ls_MoverCorriente(project,LS_SIGUIENTE));

        ls_Vaciar(project); /*borro la lista de proyectos*/
    }
    return RES_OK;

}

int Cerrar_Incidencias(TListaSimple* incidencias)
{
    TIN inciaux;
    int error;

    if(ls_MoverCorriente(incidencias,LS_PRIMERO))
    {
        do{ /*recorro la lista de incidencias, liberando el contenido con LIBERAR*/
            ls_ElemCorriente(*incidencias,&inciaux);
            error=TIN_Liberar(&inciaux);
            if (error==-1) /*si hubo error en LIBERAR devuelve error x standard error*/
            {

                return ERR_UNDEFINED;
            }

        }while (ls_MoverCorriente(incidencias,LS_SIGUIENTE)); /*Termina cuando no existe SIGUIENTE*/

        ls_Vaciar(incidencias); /*borro la lista de incidencias*/
    }

    return RES_OK;

}

int TGI_Cerrar( TGI* tgi )
{
    Cerrar_Project(&tgi->proyectos); /*borro la lista de proyectos, liberando memoria antes*/
    Cerrar_User(&tgi->usuarios); /*borro la lista de usuarios, liberarndo memoria din�mica antes*/

    if (Cerrar_Incidencias(&tgi->incidencias)==ERR_UNDEFINED)
    {
        fprintf(stderr,"%s","ERROR AL CERRAR INCIDENCIAS");
        return -1;
    }

    return RES_OK;
}
